﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;

/// <summary>
/// 切换子节点的显示状态开关
/// todo 可以增加对其他组件的支持
/// 190916 - 更新反向获取顺序，方便反转获取子节点的顺序
/// </summary>
[ExecuteInEditMode]
[AddComponentMenu("UI/Behavior/SwitchChild")]
public class UISwitchChild : MonoBehaviour,IUIIndex
{

    [Tooltip("应用的父对象, 默认为自身")]
    public Transform parent = null;
    public enum MODE
    {
        SELECT_ONE,
        DISPLAY_COUNT,
        HIDE_COUNT,
    }

    public enum ACTION
    {
        OBJECT_ACTIVE,
        FRAME_INDEX,
        COLOR_INDEX,
        SCALE_ZERO,
    }

    [Tooltip("比较模式,SELECT_ONE = 显示等于index 的子节点,\n DISPLAY_COUNT = 显示指定数量的子节点,\n HIDE_COUNT = 隐藏指定数量的子节点")]
    public MODE mode = MODE.SELECT_ONE;

    [Tooltip("比较模式,OBJECT_ACTIVE = 显示或隐藏,\n FRAME_INDEX = 设置 FRAME_INDEX 的值")]
    public ACTION action = ACTION.OBJECT_ACTIVE;

    private void Awake()
    {
        if (parent == null) parent = transform;
    }

    [SerializeField]
    private int _index;
    public int index
    {
        get
        {
            return _index;
        }
        set
        {
            var max = (mode != MODE.SELECT_ONE) ? parent.childCount : (parent.childCount - 1);
            if (value > max) value = max;
            if (value < 0) value = 0;
            UpdateFromIndex(value);
            _index = value;
        }
    }

    [Tooltip("是否翻转序号,适合反向改变子节点的状态,比如格斗游戏中左右两边方向不同的条")]
    public bool isReverse = false;

#if UNITY_EDITOR
    bool _dirty = false;
    private void OnValidate()
    {
        if (parent == null) parent = transform;
        var max = (mode != MODE.SELECT_ONE) ? parent.childCount : (parent.childCount - 1);
        if (_index > max) _index = max;
        if (_index < 0) _index = 0;
        _dirty = true;
    }

    private void Update()
    {
        if (_dirty)
        {
            _dirty = false;
            UpdateFromIndex(_index);
        }
    }

#endif

    public Vector3 GetChildPosition(int index)
    {
        var max = parent.childCount - 1;
        if (index > max) index = max;
        if (index < 0) index = 0;
        var child = parent.GetChild(isReverse ? max - index : index);
        Vector3 pos = new Vector3();
        if (child) pos = child.position;
        return pos;
    }

    [System.Obsolete]
    /// <summary>
    /// 获取当前显示的子对象,不建议使用，因为方法不稳定
    /// 试用 GetActiveChild 代替
    /// </summary>
    /// <returns></returns>
    public GameObject GetCurrentChild()
    {

        Transform child = null;
        int targetIndex = 0;

        switch (mode)
        {
            case MODE.DISPLAY_COUNT:
                targetIndex = this._index - 1;
                break;
            case MODE.HIDE_COUNT:
                targetIndex = this._index;
                break;
            case MODE.SELECT_ONE:
                targetIndex = this._index;
                break;
        }

        foreach (Transform item in this.transform)
        {
            if (item.GetSiblingIndex() == targetIndex)
            {
                return child.gameObject;
            }
        }

        return null;
    }


    public Transform GetActiveChild()
    {
        foreach (Transform trans in this.transform)
        {
            if (trans)
            {
                if (trans.gameObject.activeSelf)
                {
                    return trans;
                }
            }
        }

        return null;
    }


    public int GetMaxIndex()
    {
        return this.parent.childCount;
    }

    private void UpdateFromIndex(int value)
    {

        for (int i = 0; i < this.parent.childCount; i++)
        {
            bool res = false;
            var child = this.parent.GetChild(isReverse ? (this.parent.childCount - 1 - i) : i);
            switch (mode)
            {

                case MODE.SELECT_ONE:
                    res = i == value ? true : false;
                    break;
                case MODE.HIDE_COUNT:
                    res = i >= value ? true : false;

                    break;
                case MODE.DISPLAY_COUNT:
                    res = i < value ? true : false;
                    break;
                default:
                    break;
            }

            switch (action)
            {
                case ACTION.OBJECT_ACTIVE:
                    child.gameObject.SetActive(res);
                    break;
                case ACTION.SCALE_ZERO:
                    child.transform.localScale = res ? Vector3.one : Vector3.zero;
                    break;
                case ACTION.FRAME_INDEX:
                    var comp = child.GetComponent<UIFrameIndex>();
                    if (comp) comp.index = res ? 1 : 0;
                    break;
                case ACTION.COLOR_INDEX:
                    var comp2 = child.GetComponent<UIColorIndex>();
                    if (comp2) comp2.index = res ? 1 : 0;
                    break;
                default: break;
            }
        }


    }
}
